#ifndef __LSTRING_H__
#define __LSTRING_H__

namespace common
{

template<typename T, typename __ST = unsigned int> class _string
{
public:
   typedef __ST size_t;
   typedef T value_type;

   typedef _string<T, __ST> self_t;
public:
   size_t length() const;

   size_t index_of(const value_type &_c) const;
   size_t index_of(const value_type &_c, const size_t &_start) const;
   size_t index_of(const value_type &_c, const size_t &_start,
            const size_t &_end) const;

   size_t index_of(const self_t &_value) const;
   size_t index_of(const self_t &_value,const size_t &_start) const;
   size_t index_of(const self_t &_value,const size_t &_start,const size_t &_end) const;

   bool contains(const self_t &_value) const;

   self_t& operator<<(const value_type &_value);
   self_t& operator<<(const self_t &_value);
   self_t& operator<<(const char *_value);

   value_type& operator[](const size_t &_index) const;
   value_type& at(const size_t &_index) const;

   self_t operator+(const self_t &_other) const;
   self_t operator+(const value_type &_other) const;

   int to_int() const;
   unsigned int to_unsigned_int() const;
   long to_long() const;
   double to_double() const;
   long double to_long_double() const;

   self_t& reverse();
   self_t& swap(self_t& _other);

   self_t& replace_all(const self_t &_old,const self_t &_new);
   self_t& replace_all(const self_t &_old,const self_t &_new, const size_t &_start);
   self_t& replace_all(const self_t &_old,const self_t &_new, const size_t &_start,const size_t &_end);

   self_t& replace_all(const value_type &_old,const value_type &_new);
   self_t& replace_all(const value_type &_old,const value_type &_new, const size_t &_start);
   self_t& replace_all(const value_type &_old,const value_type &_new, const size_t &_start, const size_t &_end);

   size_t find_first(const self_t &_other);
   size_t find_next(const self_t &_other);

   self_t& to_upper_case();
   self_t& to_lower_case();
   self_t& camel_case_to_c();
   self_t& c_to_camel_case();

   self_t& trim();
   self_t& trim_front();
   self_t& trim_back();

   // constructors
   _string();
   _string(const self_t &_other);
   _string(const int &_other);
   _string(const unsigned int &_other);
   _string(const float &_other);
   _string(const double &_other);
   _string(const long double &_other);
   _string(const char *_c_str);

   self_t clone() const;
};

}
#endif
